package com.eipv.multidatasource.service.impl;

import com.eipv.component.mybatis.base.entity.AbstractUser;
import com.eipv.component.mybatis.base.mapper.BaseMapper;
import com.eipv.component.mybatis.base.service.impl.BaseServiceImpl;
import com.eipv.component.snowflake.SnowflakeIdWorker;
import com.eipv.multidatasource.component.cache.PoolCache;
import com.eipv.multidatasource.component.cache.TableCache;
import com.eipv.multidatasource.component.pool.MigrateThreadPool;
import com.eipv.multidatasource.component.task.ReadAndWriteFileTask;
import com.eipv.multidatasource.entity.Table;
import com.eipv.multidatasource.mapper.oracle.OracleTableMapper;
import com.eipv.multidatasource.service.TableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class TableServiceImpl extends BaseServiceImpl<Table, String> implements TableService {

    @Autowired
    private OracleTableMapper oracleTableMapper;

    @Override
    public void migrate() {
        PoolCache.started();
        List<Table> tables = TableCache.TABLES_OF_NEED_MIGRATE;
        AtomicLong total = new AtomicLong(0);
        long start = System.currentTimeMillis();
        tables.parallelStream().forEach(table -> {
            String tableName = table.getTableName();
            long count = table.getCount();
            int num1 = (int) count / 5000;
            int num2 = (int) count % 5000;
            int page = num1 + 1;
            int pageSize = num1 == 0 ? num2 : 5000;
            pageSize = count == 0 ? 1 : pageSize;
            for (int pageNum = 1; pageNum <= page; pageNum++) {

                if (pageNum == page && num2 != 0) {
                    pageSize = num2;
                }
                MigrateThreadPool.getThreadPool().execute(new ReadAndWriteFileTask(tableName, pageNum, pageSize, total, start));
            }
        });
    }

    @Override
    public String nextId() {
        return SnowflakeIdWorker.nextStringId();
    }

    @Override
    public AbstractUser getCurrentUser() {
        return null;
    }

    @Override
    public BaseMapper<Table, String> getMapper() {
        return oracleTableMapper;
    }


    @Override
    public void run() {
        this.migrate();
    }
}
